// ==UserScript== // @name Via Css隐藏规则日志 // @namespace https://viayoo.com/ // @version 2.2 // @license MIT // @description 格式化CSS规则,检测哪些规则生效,并输出匹配日志。 // @author Copilot // @run-at document-start // @match *://*/* // @grant GM_registerMenuCommand // @grant GM_setValue // @grant GM_getValue // @require https://cdn.jsdelivr.net/npm/js-beautify@1.14.0/js/lib/beautify-css.js // ==/UserScript== (function() { 'use strict'; // 获取CSS文件URL function getCssFileUrl() { const currentHost = window.location.hostname; return `https://${currentHost}/via_inject_blocker.css`; } // 格式化CSS内容 function formatCss(rawCss) { try { return css_beautify(rawCss, { indent_size: 2, selector_separator_newline: true }); } catch (error) { console.error(`CSS格式化失败:${error.message}`); return null; } } // 提取有效选择器 function extractValidSelectors(rule) { if (!rule.selectorText) return []; const selectors = rule.selectorText.split(',').map(selector => selector.trim()); return selectors.filter(selector => { try { document.querySelector(selector); return true; } catch { return false; } }); } // 检测生效的CSS规则 function checkActiveRules(sheet) { const activeRules = []; if (!sheet || !sheet.cssRules) return activeRules; for (const rule of sheet.cssRules) { if (rule.selectorText) { const validSelectors = extractValidSelectors(rule); validSelectors.forEach(selector => { const elements = document.querySelectorAll(selector); if (elements.length > 0) { activeRules.push({ selector, count: elements.length }); } }); } } return activeRules; } // 检查CSS文件 async function checkCssFile() { const cssFileUrl = getCssFileUrl(); try { const response = await fetch(cssFileUrl); if (!response.ok) { alert(`无法加载CSS文件: ${cssFileUrl} (状态码: ${response.status})`); return; } const rawCss = await response.text(); if (!rawCss.trim()) { alert("CSS文件为空!"); return; } // 格式化CSS const formattedCss = formatCss(rawCss); if (!formattedCss) { alert("CSS格式化失败!"); return; } // 创建临时样式表并检测规则 const styleElement = document.createElement('style'); styleElement.textContent = formattedCss; document.head.appendChild(styleElement); const activeRules = checkActiveRules(styleElement.sheet); document.head.removeChild(styleElement); // 移除临时样式表 if (activeRules.length > 0) { let resultMessage = `检测完成!共有 ${activeRules.length} 条规则生效:\n\n`; activeRules.forEach((rule, index) => { resultMessage += `${index + 1}. 匹配规则: ##${rule.selector}\n`; resultMessage += `匹配到的元素数: ${rule.count}\n\n`; }); alert(resultMessage); } else { alert("没有发现生效的CSS规则!"); } } catch (error) { console.error("获取CSS文件失败:", error); alert("获取CSS文件失败,请检查网络连接或CSS文件!"); } } // 创建悬浮按钮功能(附带位置记忆) function createFloatingButtonForCssCheck() { const button = document.createElement("div"); button.textContent = "CSS日志"; button.style.position = "fixed"; button.style.zIndex = "10000"; button.style.width = "70px"; button.style.height = "35px"; button.style.backgroundColor = "#2d89ef"; button.style.color = "white"; button.style.borderRadius = "5px"; button.style.textAlign = "center"; button.style.lineHeight = "35px"; button.style.fontSize = "14px"; button.style.boxShadow = "0px 4px 6px rgba(0,0,0,0.1)"; button.style.cursor = "pointer"; button.style.opacity = "0.9"; button.style.transition = "opacity 0.3s, transform 0.3s"; // 读取按钮上次保存的位置(默认在右下角) const savedLeft = GM_getValue("floatingButtonLeft", window.innerWidth - 100); const savedTop = GM_getValue("floatingButtonTop", window.innerHeight - 100); button.style.left = `${savedLeft}px`; button.style.top = `${savedTop}px`; document.body.appendChild(button); // 触控移动功能 let startX, startY, startLeft, startTop; button.addEventListener("touchstart", (e) => { const touch = e.touches[0]; startX = touch.clientX; startY = touch.clientY; startLeft = parseInt(button.style.left, 10); startTop = parseInt(button.style.top, 10); }); button.addEventListener("touchmove", (e) => { const touch = e.touches[0]; const deltaX = touch.clientX - startX; const deltaY = touch.clientY - startY; button.style.left = `${startLeft + deltaX}px`; button.style.top = `${startTop + deltaY}px`; }); button.addEventListener("touchend", () => { // 保存按钮位置 GM_setValue("floatingButtonLeft", parseInt(button.style.left, 10)); GM_setValue("floatingButtonTop", parseInt(button.style.top, 10)); // 自动贴边隐藏 const rect = button.getBoundingClientRect(); if (rect.left + rect.width / 2 < window.innerWidth / 2) { button.style.left = "0px"; // 靠左 GM_setValue("floatingButtonLeft", 0); } else { button.style.left = `${window.innerWidth - rect.width}px`; // 靠右 GM_setValue("floatingButtonLeft", window.innerWidth - rect.width); } }); // 点击事件:执行检查功能 button.addEventListener("click", () => { // 使用原代码中的 checkCssFile 函数 if (typeof checkCssFile === "function") { checkCssFile(); } else { console.error("checkCssFile 函数未定义!"); } }); } // 初始化脚本 function initializeFloatingButtonScript() { const isButtonEnabled = GM_getValue("floatingButtonEnabled", false); // 添加菜单命令:用于切换悬浮按钮开关 GM_registerMenuCommand(isButtonEnabled ? "关闭悬浮按钮" : "开启悬浮按钮", () => { GM_setValue("floatingButtonEnabled", !isButtonEnabled); alert(`悬浮按钮已${isButtonEnabled ? "关闭" : "开启"}!`); location.reload(); }); if (isButtonEnabled) { createFloatingButtonForCssCheck(); } } // 注册菜单命令 GM_registerMenuCommand("检测CSS隐藏规则", checkCssFile); // 执行初始化 initializeFloatingButtonScript(); })();